#include "main.h"
int init_stack(Stack *s) {
    (*s)=malloc(sizeof(struct stack));
    (*s)->base=(int*)malloc(sizeof((*s)->base)*STACK_MAX_SIZE);
    if(!(*s)->base) {
        printf("result");
        return 1;
    }
    (*s)->top=(*s)->base;
    (*s)->number_of_elements=0;
    return 0;
}
int chTurnInt(char operator) {
    switch(operator) {
        case'0':return 0;
        case'1':return 1;
        case'2':return 2;
        case'3':return 3;
        case'4':return 4;
        case'5':return 5;
        case'6':return 6;
        case'7':return 7;
        case'8':return 8;
        case'9':return 9;
        default:return 0;
    }
}
bool is_operator(char symbol) {
    if(symbol=='+'||symbol=='-'||symbol=='/'||symbol=='*'||symbol=='('||symbol==')'||symbol=='#')return 1;
    return 0;
}

bool is_operand(char symbol) {
    if(symbol<='9'&&symbol>='1')return 1;
    return 0;
}
int push(Stack s,char operator_or_operand) {
    if(s->top-s->base==STACK_MAX_SIZE) {
        return 1;
    }
    if(is_operator(operator_or_operand)) {
        *(s->top)=operator_or_operand;
    }else if(is_operand(operator_or_operand)) {
        *(s->top)=chTurnInt(operator_or_operand);
    }else {
        *(s->top)=operator_or_operand;
    }
    s->top++;
    s->number_of_elements++;
    return 0;
};
int pop(Stack s,char * p_operator_or_operand) {
    if(s->top==s->base) {
        return 0;
    }
    *p_operator_or_operand=*(--s->top);
    s->number_of_elements--;
    return 1;
}
int get_top(Stack s,char*symbol) {
    if(s->base==s->top) {
        return 1;
    }
    *symbol=*(s->top-1);
    return 0;
}
char compare(char a,char b) {
    char sign='*';
    if(a=='-'||a=='+') {
        if(b=='+'||b=='_'||b==')'||b=='#') {
            sign='>';
            return sign;
        }
        else {
            sign='<';
            return sign;
        }
    }else if(a=='*'||a=='/') {
        if(b=='(') {
            sign='<';
            return sign;
        }else {
            sign='>';
            return sign;
        }
    }else if(a=='(') {
        if(b==')') {
            sign='=';
            return sign;
        }
        else if(b=='#') {
            return 'f';
        }else {
            sign='<';
            return sign;
        }
    }else if(a==')') {
        if(b=='(') {
            return 'f';
        }else {
            sign='>';
            return sign;
        }
    }else if(a=='#') {
        if(b==')') {
            return 'f';
        }else if(b=='#') {
            sign='y';
            return sign;
        }else {
            sign='<';
            return sign;
        }
    }return 'f';
}

int operation(int a,int b,char c) {
    switch(c) {
        case'+':return a+b;
        case'-':return a-b;
        case'*':return a*b;
        case'/':return a/b;
        default:return 0;
    }
}
int evaluate(char*expression,int*result) {
    Stack s1;
    Stack s2;
    char a;
    char b;
    int aNum;
    int bNum;
    char symbol;
    char ch;
    char oper;

    init_stack(&s1);
    init_stack(&s2);
    push(s2,*expression);
    ch=*(++expression);
    while(1) {
        if(is_operand(ch)) {
            push(s1,ch);
        }
        else if(is_operator(ch)) {
            get_top(s2,&symbol);
            switch(compare(symbol,ch)) {
                case'>':
                    pop(s1,&a);
                aNum=(int)(unsigned char)a;
                pop(s1,&b);
                bNum=(int)(unsigned char)b;
                pop(s2,&symbol);
                oper=(char)operation(bNum,aNum,symbol);
                push(s1,oper);
                get_top(s2,&symbol);
                expression--;
                break;
                case'<':
                    push(s2,ch);
                break;
                case'=':
                    pop(s2,&symbol);
                get_top(s2,&symbol);
                break;
                case'f':
                    printf("result");
                return 1;
            }
        }else {
            break;
        }
        ch=*(++expression);
    }
    get_top(s1,&symbol);
    *result=(int)(unsigned char)symbol;
    return 1;
}
int main() {
    char *expression="#3*(2+6)/4#";
    int result=0;
    evaluate(expression,&result);
    printf("result=%d\n",result);
}